import sys
from PySide6.QtWidgets import (
    QApplication,
    QWidget,
    QVBoxLayout,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QMessageBox,
    QPushButton,
    QScrollArea,
    QComboBox,
    QSpinBox,
    QCalendarWidget,
)
from PySide6 import QtCore
from PySide6.QtGui import QRegularExpressionValidator
from PySide6.QtCore import Qt, QRegularExpression
from utils.data import CodeTemplate, Fragment, FragmentType


class SettingWindow(QWidget):
    addTemplate = QtCore.Signal()

    def __init__(self):
        super().__init__()
        self.length = 1
        self.initUI()

    def updateLength(self):
        length = self.length_edit.text()
        if length == "":
            QMessageBox.information(self, "提示", "模板长度不能为空", QMessageBox.Ok)
            return
        self.length = int(length)
        self.fragmentTemplateScroll.updateLength(self.length)
        self.updateTemplateFormula()

    def updateTemplateFormula(self):
        self.formula_edit.setText(
            f"模板预览：{self.fragmentTemplateScroll.GetTemplate()}"
        )

    def UpdateDateFormat(self):
        dateFormat = self.dateFormat_edit.text()
        self.fragmentTemplateScroll.UpdateDateFormat(dateFormat)

    def initUI(self):
        layout = QVBoxLayout()

        # 添加顶部展示区域
        top_layout = QHBoxLayout()
        self.formula_edit = QLabel("模板预览")
        # self.formula_edit.setMaximumHeight(100)
        self.formula_edit.setAlignment(Qt.AlignCenter)
        top_layout.addWidget(self.formula_edit)
        layout.addLayout(top_layout)

        # 添加模板长度设置
        lengthSetting_layout = QHBoxLayout()
        lengthSetting_layout.addWidget(QLabel("模板长度:"))
        self.length_edit = QSpinBox()
        self.length_edit.setMinimum(1)
        self.length_edit.valueChanged.connect(self.updateLength)
        self.length_edit.setValue(1)
        lengthSetting_layout.addWidget(self.length_edit)
        layout.addLayout(lengthSetting_layout)

        # 添加模板列表
        template_layout = QVBoxLayout()
        self.fragmentTemplateScroll = FragmentTemplateScroll(self.length)
        self.fragmentTemplateScroll.valueChanged.connect(self.updateTemplateFormula)
        self.template_area = QScrollArea()
        self.template_area.setVerticalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAlwaysOn
        )
        self.template_area.setWidget(self.fragmentTemplateScroll)
        # template_layout.addWidget(self.fragmentTemplateScroll)
        template_layout.addWidget(self.template_area)

        layout.addLayout(template_layout)

        # 添加底部布局
        bottom_layout = QVBoxLayout()
        dateFormat_layout = QHBoxLayout()
        dateFormat_layout.addWidget(QLabel("日期格式:"))
        self.dateFormat_edit = QLineEdit()
        self.dateFormat_edit.setPlaceholderText("yyyyMMdd")
        self.dateFormat_edit.returnPressed.connect(self.UpdateDateFormat)
        dateFormat_layout.addWidget(self.dateFormat_edit)
        bottom_layout.addLayout(dateFormat_layout)
        self.addButton = QPushButton("添加模板")
        self.addButton.clicked.connect(self.addTemplate.emit)
        bottom_layout.addWidget(self.addButton)
        layout.addLayout(bottom_layout)

        self.setLayout(layout)
        self.setWindowTitle("模板设置")
        self.setGeometry(100, 100, 700, 600)
        self.setFixedSize(self.width(), self.height())


class FragmentTemplateScroll(QWidget):
    valueChanged = QtCore.Signal()

    def __init__(self, length: int):
        super().__init__()
        self.length = length
        self.fragmentTemplate_list = []
        self.separators_list = []
        self.dateFormate = "yyyyMMdd"

        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignTop)
        self.setLayout(self.layout)

        self.updateLength(length)

    def updateLength(self, length: int):
        self.length = length
        self.setFixedHeight(100 * length - 50)
        fragmentTemplate_list_len = len(self.fragmentTemplate_list)

        if fragmentTemplate_list_len == length:
            return
        elif fragmentTemplate_list_len < length:
            self.addFragmentTemplate(length - fragmentTemplate_list_len)
        else:
            self.deleteFragmentTemplate(fragmentTemplate_list_len - length)

        if len(self.separators_list) == len(self.fragmentTemplate_list):
            self.separators_list.pop(0).deleteLater()

    def addFragmentTemplate(self, length: int):
        for i in range(length):
            separator = SeparatorTemplate()
            separator.valueChanged.connect(self.valueChanged.emit)
            self.separators_list.append(separator)
            self.layout.addWidget(separator)

            fragmentTemplate = FragmentTemplate()
            fragmentTemplate.valueChanged.connect(self.valueChanged.emit)
            self.fragmentTemplate_list.append(fragmentTemplate)
            self.layout.addWidget(fragmentTemplate)
            self.show()

    def deleteFragmentTemplate(self, length: int):
        for i in range(length):
            self.fragmentTemplate_list.pop().deleteLater()
            self.separators_list.pop().deleteLater()

    def GetTemplate(self):
        fragments = []
        for fragmentTemplate in self.fragmentTemplate_list:
            fragments.append(fragmentTemplate.GetFragment())
        separators = []
        for separator in self.separators_list:
            separators.append(separator.GetSeparator())
        return CodeTemplate(fragments, separators, self.dateFormate)

    def UpdateDateFormat(self, dateFormat: str):
        self.dateFormate = dateFormat
        for fragmentTemplate in self.fragmentTemplate_list:
            fragmentTemplate.UpdateDateFormat(dateFormat)


class SeparatorTemplate(QWidget):
    valueChanged = QtCore.Signal()

    def __init__(self):
        super().__init__()
        self.setMinimumHeight(10)
        self.setMaximumHeight(50)

        valueType_lable = QLabel("连接符：")
        self.valueType_box = QComboBox()
        self.valueType_box.addItems(["-", "_"])
        self.valueType_box.currentIndexChanged.connect(self.valueChangedCallback)
        self.valueType_box.setMaximumWidth(50)

        layout = QHBoxLayout()
        layout.addWidget(valueType_lable)
        layout.addWidget(self.valueType_box)
        self.setLayout(layout)

    def valueChangedCallback(self, x):
        self.valueChanged.emit()

    def GetSeparator(self):
        return self.valueType_box.currentText()


class FragmentTemplate(QWidget):
    valueChanged = QtCore.Signal()

    def __init__(self):
        super().__init__()
        self.setMinimumHeight(40)
        self.setMaximumHeight(50)

        self.type = FragmentType.string

        neme_lable = QLabel("输入名称：")
        self.name_edit = QLineEdit()
        # self.name_edit.setPlaceholderText("编号")
        valueType_lable = QLabel("输入值类型：")
        self.valueType_box = QComboBox()
        self.valueType_box.addItems(["数字", "字符", "日期"])
        self.valueType_box.currentIndexChanged.connect(self.typeChangedCallback)
        initValue_lable = QLabel("输入初始值：")
        self.initValue_edit = InitLineEdit()
        self.initValue_edit.textChanged.connect(self.valueChangedCallback)
        # self.initValue_edit_date = QDateTimeEdit()
        # self.initValue_edit_date.setDisplayFormat("yyyyMMdd")
        # self.initValue_edit_date.setMinimumWidth(150)
        # self.initValue_edit_date.dateTimeChanged.connect(self.valueChangedCallback)
        self.typeChanged()

        layout = QHBoxLayout()
        layout.addWidget(neme_lable)
        layout.addWidget(self.name_edit)
        layout.addWidget(valueType_lable)
        layout.addWidget(self.valueType_box)
        layout.addWidget(initValue_lable)
        layout.addWidget(self.initValue_edit)
        # layout.addWidget(self.initValue_edit_date)
        self.setLayout(layout)

    def valueChangedCallback(self, x):
        self.valueChanged.emit()

    def typeChangedCallback(self, x):
        self.typeChanged()

    def typeChanged(self):
        currentType = self.currentType()
        self.initValue_edit.updateType(currentType)

    def currentType(self):
        valueType_txt = self.valueType_box.currentText()
        if valueType_txt == "数字":
            valueType = FragmentType.number
        elif valueType_txt == "字符":
            valueType = FragmentType.string
        elif valueType_txt == "日期":
            valueType = FragmentType.date
        else:
            raise ValueError("不支持的类型")
        return valueType

    def GetFragment(self):
        name = self.name_edit.text()
        valueType = self.currentType()
        initValue = self.initValue_edit.text()
        return Fragment(
            length=len(initValue), type=valueType, string=initValue, name=name
        )

    def UpdateDateFormat(self, dateFormat: str):
        self.initValue_edit.UpdateDateFormat(dateFormat)


class InitLineEdit(QLineEdit):
    def __init__(self):
        super().__init__()
        self.type = FragmentType.string
        self.calendar = None
        self.dateFormate = "yyyyMMdd"
        self.date = None

    def updateType(self, type: FragmentType):
        self.type = type
        self.setReadOnly(False)
        self.setText("")
        if type == FragmentType.date:
            self.setReadOnly(True)
        elif type == FragmentType.number:
            # self.setPlaceholderText("123")
            self.setValidator(
                QRegularExpressionValidator(QRegularExpression("^[0-9]+$"))
            )
        elif type == FragmentType.string:
            # self.setPlaceholderText("AAA")
            self.setValidator(
                QRegularExpressionValidator(QRegularExpression("^[A-Z]+$"))
            )

    def mouseReleaseEvent(self, QMouseEvent):
        if QMouseEvent.button() == Qt.LeftButton:
            self.showCalendar()

    def showCalendar(self):
        if self.type != FragmentType.date:
            return
        self.calendar = QCalendarWidget()
        self.calendar.setWindowFlags(Qt.Popup)
        self.calendar.move(self.mapToGlobal(self.rect().bottomLeft()))
        self.calendar.clicked.connect(self.setDate)
        self.calendar.show()

    def setDate(self, date):
        self.date = date
        self.setText(date.toString(self.dateFormate))
        self.calendar.close()

    def UpdateDateFormat(self, dateFormat: str):
        self.dateFormate = dateFormat
        if self.type == FragmentType.date and self.date is not None:
            self.setText(self.date.toString(self.dateFormate))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    math_plot = SettingWindow()
    math_plot.show()
    sys.exit(app.exec_())
